package com.example.meetsmart.controller;

import com.example.meetsmart.model.Booking;
import com.example.meetsmart.model.Booking.BookingStatus;
import com.example.meetsmart.service.BookingService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/api/bookings")
public class BookingController {
    private final BookingService bookingService;

    public BookingController(BookingService bookingService) {
        this.bookingService = bookingService;
    }

    @GetMapping
    @PreAuthorize("hasRole('ADMIN') or hasRole('MODERATOR')")
    public ResponseEntity<Page<Booking>> getAllBookings(Pageable pageable) {
        return ResponseEntity.ok((Page<Booking>) bookingService.getAllBookings(pageable));
    }

    @GetMapping("/{id}")
    public ResponseEntity<Booking> getBookingById(@PathVariable Long id) {
        return ResponseEntity.ok(bookingService.getBookingById(id));
    }

    @GetMapping("/user/{userId}")
    public ResponseEntity<Page<Booking>> getBookingsByUser(@PathVariable Long userId, Pageable pageable) {
        return ResponseEntity.ok((Page<Booking>) bookingService.getBookingsByUser(userId, pageable));
    }

    @GetMapping("/room/{roomId}")
    public ResponseEntity<Page<Booking>> getBookingsByRoom(@PathVariable Long roomId, Pageable pageable) {
        return ResponseEntity.ok((Page<Booking>) bookingService.getBookingsByRoom(roomId, pageable));
    }

    @GetMapping("/status/{status}")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MODERATOR')")
    public ResponseEntity<Page<Booking>> getBookingsByStatus(@PathVariable BookingStatus status, Pageable pageable) {
        return ResponseEntity.ok((Page<Booking>) bookingService.getBookingsByStatus(status, pageable));
    }

    @PostMapping
    public ResponseEntity<Booking> createBooking(
            @Valid @RequestBody Booking booking,
            @RequestParam Long userId,
            @RequestParam Long roomId) {
        return ResponseEntity.ok(bookingService.createBooking(booking, userId, roomId));
    }

    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MODERATOR')")
    public ResponseEntity<Booking> updateBookingStatus(
            @PathVariable Long id,
            @RequestParam BookingStatus status,
            @RequestParam(required = false) String rejectionReason) {
        return ResponseEntity.ok(bookingService.updateBookingStatus(id, status, rejectionReason));
    }

    @PutMapping("/{id}/cancel")
    public ResponseEntity<Booking> cancelBooking(@PathVariable Long id, @RequestParam Long userId) {
        return ResponseEntity.ok(bookingService.cancelBooking(id, userId));
    }

    @GetMapping("/current")
    public ResponseEntity<List<Booking>> findCurrentBookings() {
        return ResponseEntity.ok(bookingService.findCurrentBookings());
    }

    @GetMapping("/between")
    public ResponseEntity<Page<Booking>> findBookingsBetween(
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime end,
            Pageable pageable) {
        return ResponseEntity.ok((Page<Booking>) bookingService.findBookingsBetween(start, end, pageable));
    }
}